import os
from subprocess import call

import PIL.ExifTags
import PIL.Image
from PyPDF2 import PdfFileMerger, PdfFileReader, PdfFileWriter
from reportlab.lib.pagesizes import A4
from reportlab.lib.utils import ImageReader
from reportlab.pdfgen import canvas
from reportlab.platypus import Image


def page_rotate(in_files):
    """ 统一页面方向，竖直布局 """
    pdf_writer = PdfFileWriter()
    for file in in_files:
        in_pdf = open(file, 'rb')
        pdf_input = PdfFileReader(in_pdf)
        for i in range(pdf_input.getNumPages()):
            page = pdf_input.getPage(i)
            if is_vertical(page):
                page.rotateClockwise(90)
            pdf_writer.addPage(page)
        # in_pdf.close()
    return pdf_writer


def is_vertical(page):
    """ 判断是否竖直布局 """
    media_box = page.mediaBox
    return media_box.getUpperRight_x() - media_box.getUpperLeft_x() > media_box.getUpperRight_y() - media_box.getLowerRight_y()


def get_pdfs(files):
    pdfs = []
    imgs = []
    for file in files:
        file_path = os.path.join(mypath, file)
        if os.path.isfile(file_path):
            extension = os.path.splitext(file_path)[1].lower()
            if extension == '.pdf':
                pdfs.append(file_path)
            elif extension in ['.jpg', '.png', '.jpeg']:
                imgs.append(file_path)
    if imgs:
        output_file_name = '__images.pdf'
        img_pdf_path = os.path.join(mypath, output_file_name)
        imgs2pdf(imgs, output_file_name)
        pdfs.append(img_pdf_path)
    return pdfs


def merge_pdfs(mypath, pdf_path):
    """ 合并pdf """
    files = os.listdir(mypath)
    pdfs = get_pdfs(files)
    pdf_writer = page_rotate(pdfs)
    pdf_writer = PdfFileWriter()
    open_files = []
    for file in pdfs:
        in_pdf = open(file, 'rb')
        open_files.append(in_pdf)
        pdf_input = PdfFileReader(in_pdf)
        for i in range(pdf_input.getNumPages()):
            page = pdf_input.getPage(i)
            if is_vertical(page):
                page.rotateClockwise(270)
            pdf_writer.addPage(page)
    out_file = open(pdf_path, 'wb')
    pdf_writer.write(out_file)
    out_file.close()
    for file in open_files:
        file.close()


def rotate_img_to_proper(image):
    try:
        # image = Image.open(filename)
        if hasattr(image, '_getexif'):  # only present in JPEGs
            for orientation in PIL.ExifTags.TAGS.keys():
                if PIL.ExifTags.TAGS[orientation] == 'Orientation':
                    break
            e = image._getexif()  # returns None if no EXIF data
            if e is not None:
                #log.info('EXIF data found: %r', e)
                exif = dict(e.items())
                orientation = exif[orientation]
                # print('found, ',orientation)
                if orientation == 3:
                    image = image.transpose(Image.ROTATE_180)
                elif orientation == 6:
                    image = image.transpose(Image.ROTATE_270)
                elif orientation == 8:
                    image = image.rotate(90, expand=True)
    except:
        pass
    return image


def imgs2pdf(imgs, output_file_name='__images.pdf'):
    """ 图片生成pdf """
    imgDoc = canvas.Canvas(output_file_name)
    document_width, document_height = A4
    for image in imgs:
        try:
            image_file = PIL.Image.open(image)
            image_file = rotate_img_to_proper(image_file)
            image_width, image_height = image_file.size
            if not(image_width > 0 and image_height > 0):
                raise Exception
            image_aspect = image_height / float(image_width)
            # Determins the demensions of the image in the overview
            print_width = document_width
            print_height = document_width * image_aspect
            imgDoc.setPageSize(image_file.size)
            imgDoc.drawImage(
                ImageReader(image_file),
                0,
                0,
                image_width,
                image_height,
                preserveAspectRatio=True
            )
            # inform the reportlab we want a new page
            imgDoc.showPage()
        except Exception as e:
            print('error:', e, image)
    imgDoc.save()


if __name__ == "__main__":
    mypath = os.getcwd()
    out_file = os.path.join(mypath, '__merger.pdf')
    if os.path.exists(out_file):
        os.remove(out_file)
    pdf_path = os.path.join(mypath, out_file)
    merge_pdfs(mypath, pdf_path)
    acrobat = r"D:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
    call([acrobat, "/p", pdf_path])
